package com.gitee.l0km.beanfilter.core;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 用于向序列化/反序列化器提供当前上拦截器下文有效的{@link SupplyFilter}实例
 * 
 * @author guyadong
 *
 */
public class LocalSupplyFilter {
	private final Class<?> beanClass;
	private final RequestPhase phase;
	private final CodecScene scene;
	private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
	private volatile SupplyFilter supplyFilter = SupplyFilter.DEFAULT_INSTANCE;

	/**
	 * @param beanClass 序列化/反序列化器对应的Java Bean类型
	 * @param phase     序列化/反序列化器对应的工作环境类型
	 * @param scene     序列化/反序列化器对应的编解码场景
	 */
	public LocalSupplyFilter(Class<?> beanClass, RequestPhase phase, CodecScene scene) {
		this.beanClass = checkNotNull(beanClass, "beanClass is null");
		this.phase = checkNotNull(phase, "phase is null");
		this.scene = checkNotNull(scene, "scene is null");
	}

	/**
	 * 根据服务方法拦截器上下文返回{@link SupplyFilter}实例<br>
	 * 根据服务方法拦截器上下文中当前线程的 {@link IFilterContainer}返回的关联类型集合判断，
	 * 如果当前类型不在关联类型中则返回{@link SupplyFilter} 默认实例,即禁用过滤器
	 */
	public SupplyFilter getSupplyFilter() {
		readWriteLock.readLock().lock();
		try {
			if (SupplyFilter.DEFAULT_INSTANCE  != supplyFilter) {
				IFilterContainer localContainer = InterceptorContext.getCurrentFilterContainer();
				if (null != localContainer && localContainer != IFilterContainer.DEFAULT_INSTANCE) {
					boolean associated = localContainer.associateClasses(phase.phase, scene.scope).contains(beanClass);
					return associated ? supplyFilter : SupplyFilter.DEFAULT_INSTANCE;
				}
			}
			return supplyFilter;
		} finally {
			readWriteLock.readLock().unlock();
		}
	}

	public void setSupplyFilter(SupplyFilter supplyFilter) {
		readWriteLock.writeLock().lock();
		try {
			if (null != supplyFilter && SupplyFilter.DEFAULT_INSTANCE != supplyFilter) {
				this.supplyFilter = supplyFilter;
			}
		} finally {
			readWriteLock.writeLock().unlock();
		}
	}
}
